From 266866e82c1460c268435cf8a6faf466b65727e8 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Tue, 3 Jan 2012 10:51:13 -0500 Subject: [PATCH] Fix problems with DND on some X servers When the X server does not support the shape extension (as some vnc implementations seem to), our DND code was always seeing an empty input shape, so drops always missed their target. http://bugzilla.gnome.org/show_bug.cgi?id=620240 --- gdk/x11/gdkdnd-x11.c | 13 +++++++++---- gdk/x11/gdkwindow-x11.c | 23 +++++++++++++++-------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/gdk/x11/gdkdnd-x11.c b/gdk/x11/gdkdnd-x11.c index 80467fabdb..62e351c938 100644 --- a/gdk/x11/gdkdnd-x11.c +++ b/gdk/x11/gdkdnd-x11.c @@ -662,11 +662,16 @@ is_pointer_within_shape (GdkDisplay *display, GdkX11Display *display_x11 = GDK_X11_DISPLAY (display); cairo_region_t *input_shape; - child->shape = _gdk_x11_xwindow_get_shape (display_x11->xdisplay, - child->xid, ShapeBounding); + child->shape = NULL; + if (gdk_display_supports_shapes (display)) + child->shape = _gdk_x11_xwindow_get_shape (display_x11->xdisplay, + child->xid, ShapeBounding); #ifdef ShapeInput - input_shape = _gdk_x11_xwindow_get_shape (display_x11->xdisplay, - child->xid, ShapeInput); + input_shape = NULL; + if (gdk_display_supports_input_shapes (display)) + input_shape = _gdk_x11_xwindow_get_shape (display_x11->xdisplay, + child->xid, ShapeInput); + if (child->shape && input_shape) { cairo_region_intersect (child->shape, input_shape); diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c index 6613801eef..7773fd7497 100644 --- a/gdk/x11/gdkwindow-x11.c +++ b/gdk/x11/gdkwindow-x11.c @@ -3890,17 +3890,24 @@ _gdk_x11_xwindow_get_shape (Display *xdisplay, shape = NULL; rn = 0; - xrl = XShapeGetRectangles (xdisplay, - window, - shape_type, &rn, &ord); + /* Note that XShapeGetRectangles returns NULL in two situations: + * - the server doesn't support the SHAPE extension + * - the shape is empty + * + * Since we can't discriminate these here, we always return + * an empty shape. It is the callers responsibility to check + * whether the server supports the SHAPE extensions beforehand. + */ + xrl = XShapeGetRectangles (xdisplay, window, shape_type, &rn, &ord); - if (xrl == NULL || rn == 0) + if (rn == 0) return cairo_region_create (); /* Empty */ if (ord != YXBanded) { /* This really shouldn't happen with any xserver, as they - generally convert regions to YXBanded internally */ + * generally convert regions to YXBanded internally + */ g_warning ("non YXBanded shape masks not supported"); XFree (xrl); return NULL; @@ -3915,10 +3922,10 @@ _gdk_x11_xwindow_get_shape (Display *xdisplay, rl[i].height = xrl[i].height; } XFree (xrl); - + shape = cairo_region_create_rectangles (rl, rn); g_free (rl); - + return shape; } @@ -3940,7 +3947,7 @@ gdk_x11_window_get_input_shape (GdkWindow *window) { #if defined(ShapeInput) if (!GDK_WINDOW_DESTROYED (window) && - gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window))) + gdk_display_supports_input_shapes (GDK_WINDOW_DISPLAY (window))) return _gdk_x11_xwindow_get_shape (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), ShapeInput); -- 2.30.2